/********************************************************************************
 * @file    smart_timer.c
 * @brief   智能定时器应用组件
 * 
 * @author  nzttj
 * @date    2025-04-02
 * @version 1.0
 * 
 * Copyright (C) 2025 nzttj
 * 
 * 本软件使用 GNU 通用公共许可证 (GPL) 第 3 版授权。
 * 
 * 您可以自由使用、修改、分发本软件，但必须遵守以下条件：
 * 1. 源代码必须开放，且您修改后的代码也必须以 GPL 许可证发布。
 * 2. 发布或分发本软件时，必须附带本许可证，并提供源代码或获取源代码的方式。
 * 
 * 本软件按"原样"提供，不附带任何担保，使用风险由用户自行承担。
 * 
 ********************************************************************************/

#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_err.h"

#include "smart_timer.h"
#include "timer_scheduler.h"
#include "timer_storage.h"

static const char *TAG = "smart_timer";

/**
 * @brief 智能定时器全局上下文结构体
 */
typedef struct {
    timer_scheduler_t scheduler;    ///< 定时器调度器实例
    SemaphoreHandle_t mutex;       ///< 互斥锁，用于保护共享资源
    bool initialized;              ///< 组件初始化状态标志
} smart_timer_ctx_t;

/** @brief 全局上下文实例 */
static smart_timer_ctx_t g_ctx;

/**
 * @brief ESP错误码转换为定时器错误码
 * @param err ESP错误码
 * @return timer_err_t 对应的定时器错误码
 */
static timer_err_t convert_esp_err(esp_err_t err)
{
    switch (err) {
        case ESP_OK:
            return TIMER_OK;
        case ESP_ERR_NO_MEM:
            return TIMER_ERR_NO_MEM;
        case ESP_ERR_INVALID_ARG:
            return TIMER_ERR_INVALID_ARG;
        case ESP_ERR_INVALID_STATE:
            return TIMER_ERR_INVALID_STATE;
        case ESP_ERR_TIMEOUT:
            return TIMER_ERR_TIMEOUT;
        case ESP_ERR_NOT_FOUND:
            return TIMER_ERR_NOT_FOUND;
        default:
            return TIMER_ERR_STORAGE;
    }
}

/**
 * @brief 初始化智能定时器组件
 * 
 * 该函数完成以下初始化工作：
 * 1. 创建互斥锁
 * 2. 初始化定时器调度器
 * 3. 初始化存储系统
 * 4. 从存储加载定时器配置
 * 5. 启动定时器调度器
 * 
 * @param max_timers 支持的最大定时器数量
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_init(uint8_t max_timers)
{
    if (g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    // 创建互斥锁
    g_ctx.mutex = xSemaphoreCreateMutex();
    if (!g_ctx.mutex) {
        return TIMER_ERR_NO_MEM;
    }

    // 初始化调度器
    esp_err_t err = timer_scheduler_init(&g_ctx.scheduler, max_timers);
    if (err != ESP_OK) {
        vSemaphoreDelete(g_ctx.mutex);
        return convert_esp_err(err);
    }

    // 初始化存储
    err = nvs_storage.init();
    if (err != ESP_OK) {
        timer_scheduler_deinit(&g_ctx.scheduler);
        vSemaphoreDelete(g_ctx.mutex);
        return convert_esp_err(err);
    }

    // 从存储加载定时器配置
    uint8_t count = max_timers;
    err = nvs_storage.load_timers(g_ctx.scheduler.timers, &count, max_timers);
    if (err != ESP_OK) {
        ESP_LOGW(TAG, "Failed to load timers from storage: %d", err);
    } else {
        g_ctx.scheduler.timer_count = count;
    }

    // 启动调度器
    err = timer_scheduler_start(&g_ctx.scheduler);
    if (err != ESP_OK) {
        timer_scheduler_deinit(&g_ctx.scheduler);
        nvs_storage.deinit();
        vSemaphoreDelete(g_ctx.mutex);
        return convert_esp_err(err);
    }

    g_ctx.initialized = true;
    return TIMER_OK;
}

/**
 * @brief 添加新的定时器
 * 
 * @param config 定时器配置
 * @param timer_id 返回的定时器ID
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_add(const timer_config_t *config, uint8_t *timer_id)
{
    if (!g_ctx.initialized || !config || !timer_id) {
        return TIMER_ERR_INVALID_ARG;
    }

    // 直接调用调度器的添加函数
    return timer_scheduler_add(&g_ctx.scheduler, config, timer_id);
}

/**
 * @brief 注册定时器触发回调函数
 * 
 * @param callback 回调函数指针
 * @param user_data 用户数据指针
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_register_callback(void (*callback)(uint8_t timer_id, timer_action_t action, void *user_data), void *user_data)
{
    if (!g_ctx.initialized || !callback) {
        return TIMER_ERR_INVALID_ARG;
    }

    xSemaphoreTake(g_ctx.mutex, portMAX_DELAY);
    g_ctx.scheduler.callback_ctx.callback = callback;
    g_ctx.scheduler.callback_ctx.user_data = user_data;
    xSemaphoreGive(g_ctx.mutex);

    return TIMER_OK;
}

/**
 * @brief 反初始化智能定时器组件
 * 
 * 该函数完成以下清理工作：
 * 1. 停止定时器调度器
 * 2. 反初始化调度器
 * 3. 反初始化存储系统
 * 4. 删除互斥锁
 * 
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_deinit(void)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    // 停止调度器
    esp_err_t err = timer_scheduler_stop(&g_ctx.scheduler);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to stop scheduler: %d", err);
        return convert_esp_err(err);
    }

    // 反初始化调度器
    err = timer_scheduler_deinit(&g_ctx.scheduler);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to deinit scheduler: %d", err);
        return convert_esp_err(err);
    }

    // 反初始化存储
    err = nvs_storage.deinit();
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to deinit storage: %d", err);
        return convert_esp_err(err);
    }

    // 删除互斥锁
    if (g_ctx.mutex) {
        vSemaphoreDelete(g_ctx.mutex);
        g_ctx.mutex = NULL;
    }

    g_ctx.initialized = false;
    return TIMER_OK;
}

/**
 * @brief 删除指定的定时器
 * 
 * @param timer_id 要删除的定时器ID
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_delete(uint8_t timer_id)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    return timer_scheduler_delete(&g_ctx.scheduler, timer_id);
}

/**
 * @brief 删除所有定时器
 * 
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_delete_all(void)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    return timer_scheduler_delete_all(&g_ctx.scheduler);
}

/**
 * @brief 更新定时器配置
 * 
 * @param config 新的定时器配置
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_update(const timer_config_t *config)
{
    if (!g_ctx.initialized || !config) {
        return TIMER_ERR_INVALID_STATE;
    }

    // 验证配置
    if (config->time.hour >= 24 || config->time.minute >= 60 || config->time.second >= 60) {
        return TIMER_ERR_INVALID_ARG;
    }

    if (config->type > TIMER_TYPE_PERIOD) {
        return TIMER_ERR_INVALID_ARG;
    }

    if (config->action > TIMER_ACTION_TOGGLE || 
        (config->type == TIMER_TYPE_PERIOD && config->end_action > TIMER_ACTION_TOGGLE)) {
        return TIMER_ERR_INVALID_ARG;
    }

    return timer_scheduler_update(&g_ctx.scheduler, config);
}

/**
 * @brief 设置定时器启用状态
 * 
 * @param timer_id 定时器ID
 * @param enable 是否启用
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_set_enabled(uint8_t timer_id, bool enable)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    return timer_scheduler_set_enabled(&g_ctx.scheduler, timer_id, enable);
}

/**
 * @brief 获取定时器列表
 * 
 * @param timers 定时器配置数组
 * @param count 输入时表示数组大小，输出时表示实际定时器数量
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_get_list(timer_config_t *timers, uint8_t *count)
{
    if (!g_ctx.initialized || !timers || !count) {
        return TIMER_ERR_INVALID_STATE;
    }

    return timer_scheduler_get_list(&g_ctx.scheduler, timers, count);
}

/**
 * @brief 获取指定定时器的配置
 * 
 * @param timer_id 定时器ID
 * @param config 返回的定时器配置
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_get(uint8_t timer_id, timer_config_t *config)
{
    if (!g_ctx.initialized || !config) {
        return TIMER_ERR_INVALID_STATE;
    }

    return timer_scheduler_get(&g_ctx.scheduler, timer_id, config);
}

/**
 * @brief 强制保存定时器配置到存储
 * 
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_save(void)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }

    xSemaphoreTake(g_ctx.mutex, portMAX_DELAY);
    esp_err_t err = nvs_storage.save_timers(g_ctx.scheduler.timers, g_ctx.scheduler.timer_count);
    xSemaphoreGive(g_ctx.mutex);

    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to save timers: %d", err);
        return convert_esp_err(err);
    }
    return TIMER_OK;
}

/**
 * @brief 获取调度器状态
 * 
 * @param running 输出参数，表示调度器是否正在运行
 * @param timer_count 输出参数，表示当前定时器数量
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_get_scheduler_status(bool *running, uint8_t *timer_count)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }
    return timer_scheduler_get_scheduler_status(&g_ctx.scheduler, running, timer_count);
}

/**
 * @brief 暂停/恢复调度器
 * 
 * @param pause 是否暂停
 * @return timer_err_t 操作结果
 */
timer_err_t smart_timer_pause_resume(bool pause)
{
    if (!g_ctx.initialized) {
        return TIMER_ERR_INVALID_STATE;
    }
    return timer_scheduler_pause_resume(&g_ctx.scheduler, pause);
}

// 其他API实现... 
